/*
    wifi soft-AP example
*/

#include "softAP.h"
#include "led.h"
#include "stdio.h"
#include "string.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_event.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "lwip/err.h"
#include "lwip/sys.h"

#define WIFI_SSID               "ESP32-WROOM-32D"       /* wifi 账号 */
#define WIFI_PASSWORD           "12345678"              /* wifi 密码 */
#define WIFI_CHANNEL            1                       /* wifi 通道 */
#define WIFI_MAX_STA_CONNECT    4                       /* wifi 最大连接设备数 */

static const char *TAG = "ESP32-WROOM-32D softAP";      /* 目标设备，串口输出信息提示时用 */

/**
  * @brief ESP32 WIFI 事件回调
  *        当有设备连接到 ESP32 softAP 时，板载 LED 蓝灯亮起，串口输出连接设备的 MAX 地址和设备个数
  *        当有设备从 ESP32 softAP 断开时，板载 LED 蓝灯熄灭，串口输出断开连接设备的 MAX 地址和设备个数 
  */
static void wifi_event_handler(void *arg, esp_event_base_t event_base, 
                                    int32_t event_id, void *event_data)
{
    /* station 连接到 softAP */
    if(event_id == WIFI_EVENT_AP_STACONNECTED)
    {
        /* 获取 wifi 连接时的事件数据 */
        wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *)event_data;
        led_on();
        /* station MAX地址、连接到ESP32 softAP设备个数 */
        ESP_LOGI(TAG, "station ["MACSTR"] connect, AID = %d\n", MAC2STR(event->mac), event->aid);
    }
    /* station 断开连接 softAP */
    else if (event_id == WIFI_EVENT_AP_STADISCONNECTED)
    {
        /* 获取 wifi 断开连接时的事件数据 */
        wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data;
        led_off();
        ESP_LOGI(TAG, "station ["MACSTR"] disconnect, AID = %d\n", MAC2STR(event->mac), event->aid);
    }
}

/**
  * @brief  初始化 ESP32 WIFI 为 softAP
  */
void wifi_init_softap(void)
{
    ESP_ERROR_CHECK(esp_netif_init());                          /* esp 网络初始化 */
    ESP_ERROR_CHECK(esp_event_loop_create_default());           /* esp 创建默认事件循环 */
    esp_netif_create_default_wifi_ap();                         /* esp 创建默认AP */

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();        /* wifi 初始化默认配置 */
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));                       /* wifi 初始化 */

    /* wifi 事件注册 */  
    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, 
                                                        ESP_EVENT_ANY_ID, 
                                                        &wifi_event_handler, 
                                                        NULL, 
                                                        NULL));

    /* wifi 配置 */
    wifi_config_t wifi_config = {
        .ap = {
            .ssid = WIFI_SSID,                                  /* wifi 账号 */
            .password = WIFI_PASSWORD,                          /* wifi 密码 */
            .ssid_len = strlen(WIFI_SSID),                      /* wifi ssid 长度 */
            .channel = WIFI_CHANNEL,                            /* wifi 通道 */
            .max_connection = WIFI_MAX_STA_CONNECT,             /* wifi 最大连接数量 */
            .authmode = WIFI_AUTH_WPA_WPA2_PSK                  /* wifi 加密模式 */
        },
    };
    /* 密码为空 */
    if(strlen(WIFI_PASSWORD) == 0)
    {
        wifi_config.ap.authmode = WIFI_AUTH_OPEN;               /* wifi 开放模式 */
    }

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));                   /* 配置 wifi 为AP模式 */
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));     /* 初始化 wifi 配置 */
    ESP_ERROR_CHECK(esp_wifi_start());                                  /* 开启 wifi */

    led_blink();
    ESP_LOGI(TAG, "esp32 wifi init softAP finished.");
}

/* demo */
void wifi_ap_mode_config_test(void)
{
    /* 初始化 Non-volation storage(NVS) 即非易失性存储 */
    esp_err_t ret = nvs_flash_init();
    if(ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());         /* 失败时擦除后再初始化 */
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    wifi_init_softap();
}
